package com.ld.shieldsb.common.core.io.img;

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import com.ld.shieldsb.common.core.util.ArithUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * 新的图片操作工具类
 * 
 * @ClassName ImgUtil
 * @author <a href="mailto:donggongai@126.com" target="_blank">kevin</a>
 * @date 2016年8月25日 下午3:12:22
 *
 */
@Slf4j
public class ImageUtil {

    /**
     * 获取图片格式
     * 
     * @param file
     *            图片文件
     * @return 图片格式
     */
    public static String getImageFormatName(File file) throws IOException {
        String formatName = null;
        try (ImageInputStream iis = ImageIO.createImageInputStream(file)) { // 自动关闭流
            Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
            if (imageReader.hasNext()) {
                ImageReader reader = imageReader.next();
                formatName = reader.getFormatName();
            }
            if (formatName != null) { // 转小写
                formatName = formatName.toLowerCase();
            }
        } catch (Exception e) {
            log.error("", e);
        }

        return formatName;
    }

    /**
     * 获取图片格式
     * 
     * @Title getImageFormatName
     * @author 吕凯
     * @date 2017年5月16日 下午4:23:16
     * @param in
     * @return
     * @throws IOException
     *             String
     */
    public static String getImageFormatName(InputStream in) throws IOException {
        String formatName = null;
        try (ImageInputStream iis = ImageIO.createImageInputStream(in)) { // 自动关闭流
            Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
            if (imageReader.hasNext()) {
                ImageReader reader = imageReader.next();
                formatName = reader.getFormatName();
            }
            if (formatName != null) { // 转小写
                formatName = formatName.toLowerCase();
            }
        } catch (Exception e) {
            log.error("", e);
        }

        return formatName;
    }

    /**
     * 检验图片格式
     * 
     * @Title isImage
     * @author 吕凯
     * @date 2017年5月16日 下午4:20:11
     * @param file
     * @return boolean
     */
    public static boolean isSupportImage(File file) {
        try {
            String formatName = getImageFormatName(file);
            IMAGE_FORMAT[] imageFormats = IMAGE_FORMAT.values();
            for (IMAGE_FORMAT format : imageFormats) {
                if (format.getValue().equals(formatName)) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 
     * 检验是否是支持的图片格式
     * 
     * @Title isSupportImage
     * @author 吕凯
     * @date 2017年5月16日 下午4:24:27
     * @param in
     * @return boolean
     */
    public static boolean isSupportImage(final InputStream in) {
        return isSupportImage(in, null);
    }

    /**
     * 
     * 检验是否是支持的图片格式
     * 
     * @Title isSupportImage
     * @author 吕凯
     * @date 2017年5月17日 上午9:02:17
     * @param in
     * @param imageFormats
     *            支持的格式
     * @return boolean
     */
    public static boolean isSupportImage(final InputStream in, IMAGE_FORMAT[] imageFormats) {
        try {
            String formatName = getImageFormatName(in);
            if (imageFormats == null) {
                imageFormats = IMAGE_FORMAT.values();
            }
            for (IMAGE_FORMAT format : imageFormats) {
                if (format.getValue().equals(formatName)) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 
     * 设置图片 高宽
     * 
     * @Title setImageSize
     * @param imageFile
     *            图片文件
     * @param width
     *            宽度
     * @param height
     *            高度
     * @return boolean
     */
    public static boolean setImageSize(File imageFile, int width, int height) {
        try {
            BufferedImage image = read(imageFile);
            if (image == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            String formatName = getImageFormatName(imageFile);
            return saveImage2File(imageFile, formatName, imageFile, width, height);
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 注意所有的读取走该方法，不要直接读取
     * 
     * @Title read
     * @author 吕凯
     * @date 2017年5月18日 上午11:16:57
     * @param imageFile
     * @return
     * @throws IOException
     *             BufferedImage
     */
    public static BufferedImage read(File imageFile) throws IOException {
        BufferedImage image = null;
        try {
            image = ImageIO.read(imageFile); // CMYK模式的jpg图片读取会出错
        } catch (IOException e) {
            image = readJpeg(imageFile);
        }
        return image;
    }

    /**
     * 写入一个 JPG 图像
     * 
     * @param im
     *            图像对象
     * @param targetJpg
     *            目标输出 JPG 图像文件
     * @param quality
     *            质量 0.1f ~ 1.0f
     */
    public static void writeJpeg(RenderedImage im, Object targetJpg, float quality) {
        try {
            ImageWriter writer = ImageIO.getImageWritersBySuffix("jpg").next();
            ImageWriteParam param = writer.getDefaultWriteParam();
            param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            param.setCompressionQuality(quality);
            ImageOutputStream os = ImageIO.createImageOutputStream(targetJpg);
            writer.setOutput(os);
            writer.write((IIOMetadata) null, new IIOImage(im, null, null), param);
            os.flush();
            os.close();
        } catch (IOException e) {
            log.error("", e);
        }
    }

    /**
     * 
     * 尝试读取JPEG文件的高级方法,可读取32位的jpeg文件
     * 
     * @Title readJpeg
     * @param imageFile
     *            图片文件
     * @return
     * @throws IOException
     *             BufferedImage
     */
    private static BufferedImage readJpeg(File imageFile) throws IOException {
        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
        ImageReader reader = null;
        while (readers.hasNext()) {
            reader = (ImageReader) readers.next();
            if (reader.canReadRaster()) {
                break;
            }
        }
        try (ImageInputStream input = ImageIO.createImageInputStream(imageFile)) {
            reader.setInput(input);
            // Read the image raster
            Raster raster = reader.readRaster(0, null);
            BufferedImage image = createJPEG4(raster);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            writeJpeg(image, out, 1);
            out.flush();
            BufferedImage img = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
            return img;
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    /**
     * 
     * Java的ImageIO无法处理4-component图像并且Java2D不能应用于AffineTransformOp,所以将栅格数据转换为RGB . Technique due to MArk Stephens. Free for any use.
     * 
     * @Title createJPEG4
     * @param raster
     * @return BufferedImage
     */
    private static BufferedImage createJPEG4(Raster raster) {
        int w = raster.getWidth();
        int h = raster.getHeight();
        byte[] rgb = new byte[w * h * 3];

        float[] Y = raster.getSamples(0, 0, w, h, 0, (float[]) null);
        float[] Cb = raster.getSamples(0, 0, w, h, 1, (float[]) null);
        float[] Cr = raster.getSamples(0, 0, w, h, 2, (float[]) null);
        float[] K = raster.getSamples(0, 0, w, h, 3, (float[]) null);

        for (int i = 0, imax = Y.length, base = 0; i < imax; i++, base += 3) {
            float k = 220 - K[i], y = 255 - Y[i], cb = 255 - Cb[i], cr = 255 - Cr[i];

            double val = y + 1.402 * (cr - 128) - k;
            val = (val - 128) * .65f + 128;
            rgb[base] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5);

            val = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128) - k;
            val = (val - 128) * .65f + 128;
            rgb[base + 1] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5);

            val = y + 1.772 * (cb - 128) - k;
            val = (val - 128) * .65f + 128;
            rgb[base + 2] = val < 0.0 ? (byte) 0 : val > 255.0 ? (byte) 0xff : (byte) (val + 0.5);
        }

        raster = Raster.createInterleavedRaster(new DataBufferByte(rgb, rgb.length), w, h, w * 3, 3, new int[] { 0, 1, 2 }, null);

        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        ColorModel cm = new ComponentColorModel(cs, false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
        return new BufferedImage(cm, (WritableRaster) raster, true, null);
    }

    /**
     * 
     * 设置图片的宽度
     * 
     * @Title setImageSize
     * @param imageFile
     *            图片文件
     * @param width
     *            宽度
     * @return boolean
     */
    public static boolean setImageSize(File imageFile, int width) {
        try {
            BufferedImage image = read(imageFile);
            if (image == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            int iw = image.getWidth();// 原始图象的宽度
            int ih = image.getHeight();// 原始图象的高度
            int height = ih;
            if (iw > width) { // 宽度超过进行缩放
                height = ih * width / iw;
                String formatName = getImageFormatName(imageFile);
                return saveImage2File(imageFile, formatName, imageFile, width, height);
            } else { // 什么都不做
                return true;
            }
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 根据限制长度等比例获取图片的宽高.
     * 
     * @title setImageSize
     * @author 张和祥
     * @date 2016年7月6日
     * @param imageFile
     *            图片文件
     * @param maxLength
     *            最大宽度
     * @return
     */
    public static BufferedImage setImageSizeByMaxLength(File imageFile, int maxLength) {
        try {
            BufferedImage image = read(imageFile);
            if (image == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return null;
            }
            int iw = image.getWidth(); // 原始图象的宽度
            int ih = image.getHeight(); // 原始图象的高度
            int height = ih;
            int width = iw;

            if (iw > maxLength) { // 如果宽度大于指定长度，等比例缩放图片宽度
                width = maxLength;
                height = ih * maxLength / iw;
            }
            if (height > maxLength) {
                width = width * maxLength / height;
                height = maxLength;
            }

            BufferedImage newImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 获取宽高时使用newImg.getWidth()和newImg.getHeight()
            return newImg;
        } catch (Exception e) {
            log.error("", e);
            return null;
        }
    }

    /**
     * 
     * 图片保存成文件
     * 
     * @Title saveImage2File
     * @param File
     *            图片
     * @param saveImageFile
     *            文件
     * @param width
     *            宽度
     * @param height
     *            高度
     * @return boolean
     */
    public static boolean saveImage2File(File image, String formatName, File saveImageFile, int width, int height) {
        if (image == null) {
            return false;
        }
        try {
            resize(image, formatName, saveImageFile, width, height);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 重新生成按指定宽度和高度的图像
     * 
     * @param File
     *            源图像文件
     * @param saveImageFile
     *            新的图像文件
     * @param _width
     *            设置新的图像宽度
     * @param _height
     *            设置新的图像高度
     */
    public static void resize(File image, String formatName, File saveImageFile, int _width, int _height) {
        resize(image, formatName, saveImageFile.getAbsolutePath(), _width, _height, 0, 0);
    }

    /**
     * 传入文件缩放，因为gif格式出入image有问题
     * 
     * @Title scale
     * @author 吕凯
     * @date 2017年5月16日 下午6:20:10
     * @param srcFile
     * @param formatName
     * @param result
     * @param _width
     * @param _height
     * @param x
     * @param y
     *            void
     */
    public static void resize(File srcFile, String formatName, String result, int _width, int _height, int x, int y) {
        try {
            BufferedImage src = read(srcFile);
            int width = src.getWidth(); // 得到源图宽
            int height = src.getHeight(); // 得到源图长

            String fomatName = "JPEG";
            BufferedImage tag = null;

            if (IMAGE_FORMAT.GIF.getValue().equals(formatName)) {// gif
//需要研究不为什么不可行
//                ByteArrayOutputStream bs = new ByteArrayOutputStream();
//                ImageIO.write(src, formatName, bs);
//                InputStream is = new ByteArrayInputStream(bs.toByteArray());

                GifUtil.resize(srcFile, new File(result), _width, _height);
                return;
            } else if (IMAGE_FORMAT.PNG.equals(formatName)) {// png
                fomatName = "PNG";
                AffineTransform transform = AffineTransform.getScaleInstance(ArithUtil.div(_width, width), ArithUtil.div(_height, height));// 只判断宽度
                AffineTransformOp transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
                tag = transformOp.filter(src, null);
            } else {// 普通
                width = _width;
                height = _height;

                Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(image, x, y, null); // 绘制缩小后的图
                g.dispose();
            }
            ImageIO.write(tag, fomatName, new File(result));// 输出到文件流
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加水印文件右下角用于编辑器上传
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件，没有可为空
     * @param markDir
     *            生成新文件路径
     * @return
     */
    public static boolean setWaterMarkRightBottom(File imageFile, File markFile, String newImgDir, int width) {
        return setWaterMarkRightBottom(imageFile, markFile, newImgDir, 1f, width); // 默认不透明

    }

    /**
     * 添加水印文件右下角用于编辑器上传
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件，没有可为空
     * @param markDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @return
     */
    public static boolean setWaterMarkRightBottom(File imageFile, File markFile, String newImgDir, float opacity, int width) {
        try {
            BufferedImage image = read(imageFile);
            if (image == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            int iw = image.getWidth();// 原始图象的宽度
            int ih = image.getHeight();// 原始图象的高度
            int height = ih;
            if (iw > width) {
                height = ih * width / iw;
            } else {
                width = iw;
            }
            return setWaterMarkRightBottom(imageFile, markFile, newImgDir, opacity, width, height);
        } catch (IOException e) {
            log.error("", e);
            return false;
        }

    }

    /**
     * 添加水印文件用于编辑器上传(注意与后面的方法合并)
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件
     * @param newImgDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @param width
     * @return
     */
    public static boolean setWaterMarkRightBottom(File imageFile, File markFile, String newImgDir, float opacity, int width, int height) {
        try {
            BufferedImage sourceBufferedImage = read(imageFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = newBufferedImage.createGraphics();
            Image image = sourceBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            g.drawImage(image, 0, 0, width, height, null); // 重绘图片大小
            if (height > 200) { // 大于200才添加水印
                // 水印文件
                if (markFile != null && markFile.exists()) {
                    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, opacity)); // 设置水印透明度

                    BufferedImage markImage = read(markFile);
                    int width_biao = markImage.getWidth();
                    int height_biao = markImage.getHeight();
                    g.drawImage(markImage, width - 150, height - 42, width_biao, height_biao, null);
                } else if (markFile != null && !markFile.exists()) {
                    log.warn("水印图片不存在：" + markFile.getAbsolutePath());
                }
            }

            g.dispose();
            // 输出图像
            String fileName = imageFile.getName();
            File markImg = new File(newImgDir);
            if (!markImg.exists()) {
                markImg.mkdirs(); // 目录不存在则创建
            }
            ImageIO.write(newBufferedImage, "JPEG", new File(newImgDir, fileName)); // 写到新的位置
            return true;
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 添加水印文件用于编辑器上传(注意与后面的方法合并)
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件，没有可为空
     * @param newImgDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @param width
     * @return
     */
    public static boolean setWaterMark(File imageFile, File markFile, String newImgDir, int width) {
        return setWaterMark(imageFile, markFile, newImgDir, 1f, width, 250, 20);
    }

    /**
     * 根据设置的水印信息添加水印文件
     * 
     * @Title setWaterMark
     * @author 吕凯
     * @date 2019年6月20日 下午3:06:14
     * @param imageFile
     * @param markFile
     * @param newImgDir
     * @param width
     * @param waterMaskInfo
     * @return boolean
     */
    public static boolean setWaterMark(File imageFile, File markFile, String newImgDir, int width, WaterMaskInfo waterMaskInfo) {
        return setWaterMark(imageFile, markFile, newImgDir, waterMaskInfo.getOpacity(), width, waterMaskInfo.getDistanceY(),
                waterMaskInfo.getDistanceX());

    }

    /**
     * 
     * 添加水印文件用于编辑器上传(注意与后面的方法合并)
     * 
     * @Title setWaterMark
     * @author 吕凯
     * @date 2019年6月20日 下午12:40:44
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件，没有可为空
     * @param newImgDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @param width
     * @return boolean
     */
    public static boolean setWaterMark(File imageFile, File markFile, String newImgDir, float opacity, int width, int distanceY,
            int distanceX) {
        try {
            BufferedImage image = read(imageFile);
            if (image == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            int iw = image.getWidth();// 原始图象的宽度
            int ih = image.getHeight();// 原始图象的高度
            int height = ih;
            if (iw > width) { // 原图宽度大于设置的宽度则进行等比例缩放
                height = ih * width / iw;
            } else {
                width = iw;
            }
            WaterMaskInfo waterMaskInfo = new WaterMaskInfo();
            waterMaskInfo.setOpacity(opacity);
            waterMaskInfo.setDistanceY(distanceY); // 上下距离
            waterMaskInfo.setDistanceX(distanceX); // 左右距离
            return setWaterMark(imageFile, markFile, newImgDir, width, height, waterMaskInfo);
        } catch (IOException e) {
            log.error("", e);
            return false;
        }

    }

    public static boolean setWaterMark(File imageFile, File markFile, String newImgDir, float opacity, int width, int height) {
        WaterMaskInfo waterMaskInfo = new WaterMaskInfo();
        waterMaskInfo.setOpacity(opacity);
        waterMaskInfo.setDistanceY(250); // 上下距离
        waterMaskInfo.setDistanceX(20); // 左右距离
        return setWaterMark(imageFile, markFile, newImgDir, width, height, waterMaskInfo);
    }

    /**
     * 添加水印文件用于编辑器上传(注意与后面的方法合并)
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件
     * @param newImgDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @param width
     * @param height
     * @return boolean
     * @return
     */

    public static boolean setWaterMark(File imageFile, File markFile, String newImgDir, int width, int height,
            WaterMaskInfo waterMaskInfo) {
        try {
            BufferedImage sourceBufferedImage = read(imageFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            // 构建新的图片
            BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            String formatName = getImageFormatName(imageFile);
            Graphics2D g = newBufferedImage.createGraphics();
            if (formatName.equals("png")) {
                // 将原图放大或缩小后画下来:并且保持png图片放大或缩小后背景色是透明的而不是黑色
                newBufferedImage = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
                g.dispose();
                g = newBufferedImage.createGraphics();
            }
            Image image = sourceBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            g.drawImage(image, 0, 0, width, height, null); // 重绘图片大小

            if (height > 200) { // 大于200才添加水印
                // 水印文件
                if (markFile != null && markFile.exists()) {
                    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, waterMaskInfo.getOpacity())); // 设置水印透明度

                    BufferedImage markImage = read(markFile);
                    int width_biao = markImage.getWidth();
                    int height_biao = markImage.getHeight();
                    g.rotate(-Math.PI / 4); // 倾斜45度，以左上角为圆点旋转
                    int distanceY = waterMaskInfo.getDistanceY(); // 上下间距
                    int distanceX = waterMaskInfo.getDistanceX(); // 左右间距
                    int markDrawWidth = width_biao + distanceX;
                    int markDrawHeight = height_biao + distanceY;

                    double bianchang = (height + width) / Math.sqrt(2);
                    double roundY = bianchang / markDrawHeight; // 旋转45度则高度刚好是长+宽处以根号2
                    double roundX = bianchang / markDrawWidth + 1;
                    // 先绘制后旋转
                    for (int i = 0; i < roundY; i++) { // y轴输出
                        for (int j = 0; j < roundX; j++) { // x轴输出，
                            // 以左上角为0点坐标，向右x向下y，10为距顶部高度,height / Math.sqrt(2)向左缩进的部分正好是height/根号2
                            g.drawImage(markImage, j * markDrawWidth - (int) (height / Math.sqrt(2)), i * markDrawHeight + 20, width_biao,
                                    height_biao, null);
                        }
                    }
                } else if (markFile != null && !markFile.exists()) {
                    log.warn("水印图片不存在：" + markFile.getAbsolutePath());
                }
            }

            g.dispose();
            // 输出图像
            String fileName = imageFile.getName();
            File markImg = new File(newImgDir);
            if (!markImg.exists()) {
                markImg.mkdirs(); // 目录不存在则创建
            }

            ImageIO.write(newBufferedImage, formatName, new File(newImgDir, fileName)); // 写到新的位置
            return true;
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 添加水印文件(默认增加4行水印)
     * 
     * @param imageFile
     *            上传文件
     * @param markFile
     *            水印文件
     * @param newImgDir
     *            生成新文件路径
     * @param opacity
     *            水印透明度
     * @param width
     *            自定义图片宽度
     * @param height
     *            自定义图片高度
     * @return
     */
    public static boolean setWaterMarkBySize(File imageFile, File markFile, String newImgDir, float opacity, int width, int height) {
        try {
            BufferedImage sourceBufferedImage = read(imageFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }

            BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = newBufferedImage.createGraphics();
            Image image = sourceBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            g.drawImage(image, 0, 0, width, height, null); // 重绘图片大小
            // 水印文件
            if (markFile != null && markFile.exists()) {
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, opacity)); // 设置水印透明度

                BufferedImage markImage = read(markFile);
                int width_biao = markImage.getWidth();
                int height_biao = markImage.getHeight();
                int heightmark = (int) (height + width * Math.sqrt(2) - 10);
                g.rotate(-Math.PI / 4); // 倾斜45度
                int distance = 150;
                for (int i = 0; i < heightmark / distance; i++) { // 先绘制后旋转
                    for (int j = 0; j < 4; j++) {
                        // g.drawImage(markImage, j * 215 - 445, 360, width_biao,
                        // height_biao, null);
                        g.drawImage(markImage, j * 215 - 445, i * distance + 5, width_biao, height_biao, null);
                    }
                }
            } else if (markFile != null && !markFile.exists()) {
                log.warn("水印图片不存在：" + markFile.getAbsolutePath());
            }

            g.dispose();
            // 输出图像
            String fileName = imageFile.getName();
            File markImg = new File(newImgDir);
            if (!markImg.exists()) {
                markImg.mkdirs();
            }
            ImageIO.write(newBufferedImage, "JPEG", new File(newImgDir, fileName));
            return true;
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 设置小图片（100x100和50x50）
     * 
     * @Title setSmallPhoto
     * @author 吕凯
     * @date 2019年6月20日 上午8:58:39
     * @param imageFile
     * @param newImgDir
     * @return boolean
     */
    public static boolean setSmallPhoto(File imageFile, String newImgDir) {
        try {
            BufferedImage sourceBufferedImage = read(imageFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            int width = 100;
            int height = 100;
            BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = newBufferedImage.createGraphics();
            Image image = sourceBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            g.drawImage(image, 0, 0, width, height, null);

            // 输出图像
            String fileName = imageFile.getName();
            File markImg = new File(newImgDir);
            if (!markImg.exists()) {
                markImg.mkdirs();
            }
            ImageIO.write(newBufferedImage, "JPEG", new File(newImgDir, fileName + ""));
            String formatName = getImageFormatName(imageFile);
            saveImage2File(imageFile, formatName, new File(newImgDir, fileName + "_min"), 50, 50);
            return true;
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 图片旋转
     * 
     * @Title rotateImg
     * @author 吕凯
     * @date 2019年6月20日 上午8:57:57
     * @param imageFile
     *            图片路径
     * @param degree
     *            旋转角度
     * @return boolean
     */
    public static boolean rotateImg(File imageFile, int degree) {
        try {
            BufferedImage image = read(imageFile);
            int iw = image.getWidth();// 原始图象的宽度
            int ih = image.getHeight();// 原始图象的高度
            int w = 0;
            int h = 0;
            int x = 0;
            int y = 0;
            degree = degree % 360;
            if (degree < 0)
                degree = 360 + degree;// 将角度转换到0-360度之间
            double ang = Math.toRadians(degree);// 将角度转为弧度

            /**
             * 确定旋转后的图象的高度和宽度
             */

            if (degree == 180 || degree == 0 || degree == 360) {
                w = iw;
                h = ih;
            } else if (degree == 90 || degree == 270) {
                w = ih;
                h = iw;
            } else {
                double cosVal = Math.abs(Math.cos(ang));
                double sinVal = Math.abs(Math.sin(ang));
                w = (int) (sinVal * ih) + (int) (cosVal * iw);
                h = (int) (sinVal * iw) + (int) (cosVal * ih);
            }

            x = (w / 2) - (iw / 2);// 确定原点坐标
            y = (h / 2) - (ih / 2);
            BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
            Graphics2D gs = (Graphics2D) rotatedImage.getGraphics();

            AffineTransform at = new AffineTransform();
            at.rotate(ang, w / 2, h / 2);// 旋转图象
            at.translate(x, y);
            gs.setTransform(at);
            gs.drawImage(image, null, null);

            ImageIO.write(rotatedImage, "JPEG", imageFile);
            return true;
        } catch (IOException e) {
            log.error("图片旋转失败", e);
        }
        return false;
    }

    /**
     * 多图合成(返回路径)
     * 
     * @param sourceFile
     *            源文件
     * @param markFile
     *            水印文件
     * @param opacity
     *            水印透明度
     * @param x
     *            水印文件left
     * @param y
     *            水印文件top
     * @param newImgDir
     *            生成新文件路径
     * @return 图片文件，如果异常返回null
     */
    public static File compositeImage(File sourceFile, File markFile, float opacity, int x, int y, String newImgDir) {
        try {
            File compositeImgFile = sourceFile;
            BufferedImage sourceBufferedImage = read(sourceFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + sourceFile.getAbsolutePath());
                return null;
            }
            int width = sourceBufferedImage.getWidth();
            int height = sourceBufferedImage.getHeight();
            BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = newBufferedImage.createGraphics();
            Image image = sourceBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
            g.drawImage(image, 0, 0, width, height, null);
            // 水印文件
            if (markFile != null && markFile.exists()) {
                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, opacity)); // 设置水印透明度

                BufferedImage markImage = read(markFile);
                g.drawImage(markImage, x, y, null);
            } else if (markFile != null && !markFile.exists()) {
                log.warn("水印图片不存在：" + markFile.getAbsolutePath());
            }

            g.dispose();
            // 输出图像
            String fileName = sourceFile.getName();
            if (newImgDir != null) {
                File markImg = new File(newImgDir);
                if (!markImg.exists()) {
                    markImg.mkdirs();
                }
                compositeImgFile = new File(newImgDir, fileName);
            }
            ImageIO.write(newBufferedImage, "JPEG", compositeImgFile);
            return compositeImgFile;
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    /**
     * 
     * 合成图片，返回布尔型
     * 
     * @Title compositeImage
     * @author 吕凯
     * @date 2017年1月3日 下午5:20:10
     * @param sourceFile
     *            源文件
     * @param markFile
     *            水印文件
     * @param x
     *            水印文件left
     * @param y
     *            水印文件top
     * @return boolean
     */
    public static boolean compositeImage(File sourceFile, File markFile, int x, int y) {
        return compositeImage(sourceFile, markFile, 1f, x, y, null) != null;
    }

    /**
     * 
     * 合成图片，返回是否成功
     * 
     * @Title compositeImage
     * @author 吕凯
     * @date 2019年6月20日 下午12:51:47
     * @param sourceFile
     *            源文件
     * @param markFile
     *            水印文件
     * @param opacity
     *            透明度
     * @param x
     * @param y
     * @return boolean
     */
    public static boolean compositeImage(File sourceFile, File markFile, float opacity, int x, int y) {
        return compositeImage(sourceFile, markFile, opacity, x, y, null) != null;
    }

    /**
     * 校验图片固定大小 长宽必须为参数值
     * 
     * @title checkFixedSize
     * @author 张和祥
     * @date 2017年3月24日
     */
    public static boolean checkFixedSize(File imageFile, int width, int height) {
        try {
            BufferedImage sourceBufferedImage = read(imageFile);
            if (sourceBufferedImage == null) {
                log.error("图片格式不正确，path:" + imageFile.getAbsolutePath());
                return false;
            }
            int imgWidth = sourceBufferedImage.getWidth(); // 上传图片宽度
            int imgHeight = sourceBufferedImage.getHeight(); // 上传图片高度
            if (imgWidth == width && imgHeight == height) {
                return true;
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 获取不包含后缀的文件路径
     * 
     * @param src
     * @return
     */
    public static String getPathWithoutSuffix(String src) {
        String path = src;
        int index = path.lastIndexOf(".");
        if (index > 0) {
            path = path.substring(0, index + 1);
        }
        return path;
    }

    /**
     * 获取真实后缀的路径，防止图片后缀与图片本身类型不一致的情况
     * 
     * @Title getRealSuffixPath
     * @author 吕凯
     * @date 2017年5月18日 上午9:40:00
     * @param src
     *            图片路径
     * @param formatName
     *            真实后缀，建议通过getImageFormatName方法获取传入
     * @return String
     */
    public static String getRealSuffixPath(String src, String formatName) {
        if (formatName == null) {
            try {
                formatName = getImageFormatName(new File(src));
            } catch (Exception e) {
                log.error("获取文件后缀出错", e);
            }
        }
        String pathPrefix = getPathWithoutSuffix(src);
        return src = pathPrefix + formatName;
    }

    /**
     * 
     * 获取真实后缀的路径，防止图片后缀与图片本身类型不一致的情况
     * 
     * @Title getRealSuffixPath
     * @author 吕凯
     * @date 2017年5月18日 上午9:43:34
     * @param src
     *            图片路径
     * @return String
     */
    public static String getRealSuffixPath(String src) {
        return getRealSuffixPath(src, null);
    }

    public static void main(String[] args) {
        // File imageFile = new
        // File("C:/Users/lv/Desktop/kevin/113516.98317523.jpg"); //宽
        File imageFile = new File("C:/Users/lv/Desktop/图片/QQ截图20170516142632_看图王.bmp"); // 高
//        File markFile = new File("E:/uploadFile/images/marks.png");
//        File markFileNew = new File("E:/uploadFile/images/marksnew.png");
        // File markFile = new File("E:/uploadFile/images/mark2news.png");
        // setWaterMarkRightBottom(imageFile, markFile,
        // "C:/Users/lv/Desktop/img", 650);
//        setWaterMark(imageFile, markFile, markFileNew, "C:/Users/lv/Desktop/img", true);
        setImageSize(imageFile, 1200, 350);
    }
}
